package november.linkedlist.doubleLinkedList;


import java.util.function.BiPredicate;

/**
 * @author huangxin
 * @date 2019/11/15-11:32
 */
public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList((curr, next) -> {
            return curr.id > next.id;
        });


        doubleLinkedList.addByBiPredicate(new Node(1, ""));
        doubleLinkedList.addByBiPredicate(new Node(5, ""));
        doubleLinkedList.addByBiPredicate(new Node(3, ""));

        doubleLinkedList.show();
        doubleLinkedList.delete(5);
        doubleLinkedList.show();
    }
}

/**
 * 单向列表
 */
class DoubleLinkedList {
    //jdk8自定义排序规则
    private BiPredicate<Node, Node> biPredicate;

    //头节点,不记录
    public Node head = new Node(0, "");

    public void add(Node node) { //
        Node temp = head;

        while (temp.next != null) {
            temp = temp.next;
        }

        //形成双向链表
        temp.next = node;
        node.pre = temp;
    }

    public void delete(int id) {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }

        Node temp = head.next;
        boolean flag = false;//是否找到
        while (temp != null) {
            if (temp.id == id) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            //temp为要删除的节点
            temp.pre.next = temp.next;
            if (temp.next!=null){
                temp.next.pre = temp.pre;
            }
        } else {
            System.out.println("没有找到该节点");
        }
    }



    /**
     * 根据排序规则插入
     *
     * @param node
     */
    public void addByBiPredicate(Node node) {
        //第一次插入
        if (head.next == null) {
            head.next = node;
            node.pre=head;
            return;
        }
        Node temp = head;
        boolean flag = false;
        //链表不为空
        while (true) {
            if (temp.next == null) {
                break;
            }
            //根据传入的排序规则判断
            if (biPredicate.test(temp.next, node)) {
                break;
            }

            if (temp.next.id == node.id) {
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag) {
            System.out.println("插入的id重复");
            return;
        }
        //插入temp.next前面
        if (temp.next !=null){
            temp.next.pre = node;
            node.next = temp.next;
        }
        node.pre = temp;
        temp.next = node;
    }

    //-----------------------下面的部分与单向链表一样

    public int count() {
        if (head.next == null) {
            return 0;
        }
        int count = 0;
        Node temp = head.next;
        while (temp != null) {
            count++;
            temp = temp.next;
        }
        return count;
    }


    public DoubleLinkedList() {
    }

    public DoubleLinkedList(BiPredicate<Node, Node> biPredicate) {
        this.biPredicate = biPredicate;
    }


    /**
     * 修改节点
     */
    public void update(Node update) {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }

        Node temp = head.next;
        boolean flag = false;//是否找到
        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.id == update.id) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            temp.name = update.name;
        } else {
            System.out.println("没有找到该节点");
        }
    }


    //打印链表
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (isEmpty()) {
            sb.append("链表为空");
            return sb.toString();
        }
        //从头节点开始打印链表
        Node temp = head.next;
        do {
            sb.append(temp.toString());
            sb.append("\n");
            temp = temp.next;
        } while (temp != null);
        return sb.toString();
    }

    public void show() {
        System.out.println(this.toString());
    }

    private boolean isEmpty() {
        return this.head.next == null;
    }
}


class Node {
    public int id;
    public String name;
    public Node next;//指向下个节点
    public Node pre;//指向上个节点


    @Override
    public String toString() {
        return "Node{" +
                "id=" + id +
                ", name=" + name +
                '}';
    }

    public Node(int id, String name) {
        this.id = id;
        this.name = name;
    }
}
